hvm: Support PUSH from mmio area (opcode 0xFF/6).
authorKeir Fraser <keir@xensource.com>
Sun, 18 Feb 2007 15:29:40 +0000 (15:29 +0000)
committerKeir Fraser <keir@xensource.com>
Sun, 18 Feb 2007 15:29:40 +0000 (15:29 +0000)
Also fix a bogus assertion in vlapic device model.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/io.c
xen/arch/x86/hvm/platform.c
xen/arch/x86/hvm/vlapic.c
xen/include/asm-x86/hvm/io.h

index 4637515bf456de2e58a89df8864248ba9d55be1d..8d369b3b49453cd8d7b9ddc33421f0cbdc107eee 100644 (file)
@@ -686,6 +686,11 @@ static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p,
             set_reg_value(size, index, 0, regs, p->data);
         }
         break;
+
+    case INSTR_PUSH:
+        mmio_opp->addr += hvm_get_segment_base(current, x86_seg_ss);
+        hvm_copy_to_guest_virt(mmio_opp->addr, &p->data, size);
+        break;
     }
 }
 
index 32246da991e62c47fb95c32e3ba1daac6d85c1fe..9ed0cd250829083ed7c211cd67b66a5ba6804560 100644 (file)
@@ -716,6 +716,11 @@ static int mmio_decode(int address_bytes, unsigned char *opcode,
             mmio_op->instr = INSTR_SUB;
             return DECODE_success;
 
+        case 6: /* push */
+            mmio_op->instr = INSTR_PUSH;
+            mmio_op->operand[0] = mmio_op->operand[1];
+            return DECODE_success;
+
         default:
             printk("%x/%x, This opcode isn't handled yet!\n",
                    *opcode, ins_subtype);
@@ -1131,6 +1136,21 @@ void handle_mmio(unsigned long gpa)
         mmio_operands(IOREQ_TYPE_XOR, gpa, mmio_op, op_size);
         break;
 
+    case INSTR_PUSH:
+        if ( ad_size == WORD )
+        {
+            mmio_op->addr = (uint16_t)(regs->esp - op_size);
+            regs->esp = mmio_op->addr | (regs->esp & ~0xffff);
+        }
+        else
+        {
+            regs->esp -= op_size;
+            mmio_op->addr = regs->esp;
+        }
+        /* send the request and wait for the value */
+        send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, op_size, 0, IOREQ_READ, df, 0);
+        break;
+
     case INSTR_CMP:        /* Pass through */
     case INSTR_TEST:
     case INSTR_SUB:
index 450dcb32378bd172ad2035a322e8854b7cbcc089..2cc294ba361cde88264e54cd69f64f3e0ae1fe4e 100644 (file)
@@ -459,7 +459,7 @@ static void vlapic_set_tdcr(struct vlapic *vlapic, unsigned int val)
 static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
                          unsigned int len, unsigned int *result)
 {
-    ASSERT((len == 4) && (offset > 0) && (offset <= APIC_TDCR));
+    ASSERT((len == 4) && (offset >= 0) && (offset <= APIC_TDCR));
 
     switch ( offset )
     {
index c71a9bbc6cdacf0eefddacbe28e7130154e72071..b08cc781cbd09634866c221040bbcb86b0bb3cbe 100644 (file)
@@ -65,6 +65,7 @@
 #define INSTR_XCHG  14
 #define INSTR_SUB   15
 #define INSTR_ADD   16
+#define INSTR_PUSH  17
 
 #define MAX_INST_LEN      15 /* Maximum instruction length = 15 bytes */